﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Services;
using IdentityServer4.Stores;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Account.Public.Web.Pages.Account;

namespace Volo.Abp.Account.Web.Pages.Account
{
	public class GrantsModel : AccountPageModel
	{
		public List<GrantsModel.GrantViewModel> Grants { get; set; }

		protected IIdentityServerInteractionService Interaction { get; }

		protected IClientStore Clients { get; }

		protected IResourceStore Resources { get; }

		public GrantsModel(IIdentityServerInteractionService interaction, IClientStore clients, IResourceStore resources)
		{
			this.Interaction = interaction;
			this.Clients = clients;
			this.Resources = resources;
		}

		public virtual async Task OnGetAsync()
		{
			this.Grants = new List<GrantsModel.GrantViewModel>();
			var list = await this.Interaction.GetAllUserConsentsAsync();
			foreach (var consent in list)
			{
				var client = await this.Clients.FindClientByIdAsync(consent.ClientId);
				if (client != null)
				{
					var result = await IResourceStoreExtensions.FindResourcesByScopeAsync(this.Resources, consent.Scopes);
					var grantViewModel = new GrantsModel.GrantViewModel();
					grantViewModel.ClientId = client.ClientId;
					grantViewModel.ClientName = (client.ClientName ?? client.ClientId);
					grantViewModel.ClientLogoUrl = client.LogoUri;
					grantViewModel.ClientUrl = client.ClientUri;
					grantViewModel.Created = consent.CreationTime;
					grantViewModel.Expires = consent.Expiration;
					grantViewModel.IdentityGrantNames = (from x in result.IdentityResources
														 select x.DisplayName ?? x.Name).ToArray<string>();
					grantViewModel.ApiGrantNames = (from x in result.ApiResources
													select x.DisplayName ?? x.Name).ToArray<string>();
					this.Grants.Add(grantViewModel);
				}
			}
		}

		public virtual async Task<IActionResult> OnPostRevokeAsync(string clientId)
		{
			await this.Interaction.RevokeUserConsentAsync(clientId);
			return base.Redirect("/");
		}

		public class GrantViewModel
		{
			public string ClientId { get; set; }

			public string ClientName { get; set; }

			public string ClientUrl { get; set; }

			public string ClientLogoUrl { get; set; }

			public DateTime Created { get; set; }

			public DateTime? Expires { get; set; }

			public IEnumerable<string> IdentityGrantNames { get; set; }

			public IEnumerable<string> ApiGrantNames { get; set; }
		}
	}
}
